/* -*- Mode: C; c-basic-offset: 4 -*-
 * pygtk- Python bindings for the GTK toolkit.
 * Copyright (C) 1998-2003  James Henstridge
 *
 *   gtkcontainer.override: overrides for various container widgets.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
 * USA
 */
%%
ignore
  gtk_container_get_toplevels
  gtk_container_add_child_arg_type
  gtk_container_query_child_args
  gtk_container_child_args_collect
  gtk_container_child_arg_get_info
  gtk_container_foreach_full
  gtk_container_add_with_args
  gtk_container_addv
  gtk_container_child_set_valist
  gtk_container_child_get_valist
  gtk_container_class_find_child_property
%%
override gtk_container_children noargs
static PyObject *
_wrap_gtk_container_children(PyGObject *self)
{
    if (PyErr_Warn(PyExc_DeprecationWarning, "use GtkContainer.get_children"))
        return NULL;
    return _wrap_gtk_container_get_children(self);
}
%%
override gtk_container_get_children noargs
static PyObject *
_wrap_gtk_container_get_children(PyGObject *self)
{
    GList *list, *tmp;
    PyObject *py_list;

    list = gtk_container_get_children(GTK_CONTAINER(self->obj));

    if ((py_list = PyList_New(0)) == NULL) {
        g_list_free(list);
        return NULL;
    }
    for (tmp = list; tmp != NULL; tmp = tmp->next) {
        PyObject *gtk_obj = pygobject_new(G_OBJECT(tmp->data));

        if (gtk_obj == NULL) {
            g_list_free(list);
            Py_DECREF(py_list);
            return NULL;
        }
        PyList_Append(py_list, gtk_obj);
        Py_DECREF(gtk_obj);
    }
    g_list_free(list);
    return py_list;
}
%%
override gtk_container_set_focus_chain kwargs
static PyObject *
_wrap_gtk_container_set_focus_chain(PyGObject *self, PyObject *args,
                                    PyObject *kwargs)
{
    static char *kwlist[] = { "focusable_widgets", NULL };
    PyObject *py_focusable_widgets;
    gint len, i;
    GList *focusable_widgets = NULL;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "O:GtkContainer.set_focus_chain", kwlist,
                                     &py_focusable_widgets))
        return NULL;
    if (!PySequence_Check(py_focusable_widgets)) {
        PyErr_SetString(PyExc_TypeError,
                        "focusable_widgets must be a sequence");
        return NULL;
    }
    len = PySequence_Length(py_focusable_widgets);
    for (i = 0; i < len; i++) {
        PyObject *item = PySequence_GetItem(py_focusable_widgets, i);

        if (!pygobject_check(item, &PyGtkWidget_Type)) {
            PyErr_SetString(PyExc_TypeError,
                            "focusable_widgets members must be GtkWidgets");
            Py_DECREF(item);
            return NULL;
        }
        focusable_widgets = g_list_prepend(focusable_widgets,
                                           pygobject_get(item));
        Py_DECREF(item);
    }
    focusable_widgets = g_list_reverse(focusable_widgets);
    gtk_container_set_focus_chain(GTK_CONTAINER(self->obj), focusable_widgets);
    g_list_free(focusable_widgets);
    Py_INCREF(Py_None);
    return Py_None;
}
%%
override gtk_container_get_focus_chain noargs
static PyObject *
_wrap_gtk_container_get_focus_chain(PyGObject *self)
{
    GList *list = NULL;

    if (gtk_container_get_focus_chain(GTK_CONTAINER(self->obj), &list)) {
        PyObject *py_list;
        GList *tmp;

        if ((py_list = PyList_New(0)) == NULL) {
            g_list_free(list);
            return NULL;
        }
        for (tmp = list; tmp != NULL; tmp = tmp->next) {
            PyObject *gtk_obj = pygobject_new(G_OBJECT(tmp->data));

            if (gtk_obj == NULL) {
                g_list_free(list);
                Py_DECREF(py_list);
                return NULL;
            }
            PyList_Append(py_list, gtk_obj);
            Py_DECREF(gtk_obj);
        }
        g_list_free(list);
        return py_list;
    }
    Py_INCREF(Py_None);
    return Py_None;
}
%%
override gtk_container_child_get_property
static PyObject *
_wrap_gtk_container_child_get_property(PyGObject *self, PyObject *args)
{
    PyGObject *pychild;
    gchar *property_name;
    GtkContainer *container;
    GtkWidget *child;
    GList *children;
    GObjectClass *class;
    GParamSpec *pspec;
    GValue value = { 0, } ;
    PyObject *ret;

    if (!PyArg_ParseTuple(args, "O!s:GtkContainer.child_get_property",
                          &PyGtkWidget_Type, &pychild,
                          &property_name)) {
        return NULL;
    }

    container = GTK_CONTAINER(self->obj);
    child = GTK_WIDGET(pychild->obj);

    children = gtk_container_get_children(container);
    if (g_list_find(children, child) == NULL) {
        PyErr_SetString(PyExc_TypeError,
                        "first argument must be a child");
        return NULL;
    }

    class = G_OBJECT_GET_CLASS(container);
    pspec = gtk_container_class_find_child_property(class, property_name);
    if (!pspec) {
        gchar buf[512];
        g_snprintf(buf, sizeof(buf),
                   "container does not support property `%s'",
                   property_name);

        PyErr_SetString(PyExc_TypeError, buf);
        return NULL;
    }

    g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));

    gtk_container_child_get_property(container,
                                     child,
                                     property_name,
                                     &value);

    ret = pyg_value_as_pyobject(&value, TRUE);
    g_value_unset(&value);

    return ret;
}
%%
override gtk_container_child_set_property
static PyObject *
_wrap_gtk_container_child_set_property(PyGObject *self, PyObject *args)
{
    gchar *property_name;
    PyGObject *pychild;
    GtkContainer *container;
    GtkWidget *child;
    GList *children;
    PyGObject *pyvalue;
    GObjectClass *class;
    GParamSpec *pspec;
    GValue value = { 0, } ;

    if (!PyArg_ParseTuple(args, "O!sO:GtkContainer.child_set_property",
                          &PyGtkWidget_Type, &pychild,
                          &property_name, &pyvalue)) {
        return NULL;
    }

    container = GTK_CONTAINER(self->obj);
    child = GTK_WIDGET(pychild->obj);

    children = gtk_container_get_children(container);
    if (g_list_find(children, child) == NULL) {
        PyErr_SetString(PyExc_TypeError,
                        "first argument must be a child");
        return NULL;
    }

    class = G_OBJECT_GET_CLASS(self->obj);
    pspec = gtk_container_class_find_child_property(class, property_name);
    if (!pspec) {
        gchar buf[512];
        g_snprintf(buf, sizeof(buf),
                   "container does not support property `%s'",
                   property_name);
        PyErr_SetString(PyExc_TypeError, buf);

        return NULL;
    }

    g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));

    pyg_value_from_pyobject(&value, (PyObject*)pyvalue);

    gtk_container_child_set_property(container,
                                     child,
                                     property_name,
                                     &value);
    g_value_unset(&value);
    Py_INCREF(Py_None);
    return Py_None;
}
%%
override gtk_container_child_set
static PyObject *
_wrap_gtk_container_child_set(PyGObject *self, PyObject *args)
{
    PyGObject *pychild;
    GtkContainer *container;
    GtkWidget *child;
    GList *children;
    GObjectClass *class;
    int len, i;

    if ((len = PyTuple_Size(args)) < 1) {
        PyErr_SetString(PyExc_TypeError, "requires at least one argument");
        return NULL;
    }
    pychild = (PyGObject*)PyTuple_GetItem(args, 0);
    if (!pygobject_check(pychild, &PyGtkWidget_Type)) {
        PyErr_SetString(PyExc_TypeError,
                        "first argument should be a GtkWidget");
        return NULL;
    }

    container = GTK_CONTAINER(self->obj);
    child = GTK_WIDGET(pychild->obj);

    children = gtk_container_get_children(container);
    if (g_list_find(children, child) == NULL) {
        PyErr_SetString(PyExc_TypeError,
                        "first argument must be a child");
        return NULL;
    }

    if ((len - 1) % 2) {
        PyErr_SetString(PyExc_TypeError,
                        "Argument list must be column, value pairs.  No -1 "
                        "termination is needed.");
        return NULL;
    }

    class = G_OBJECT_GET_CLASS(self->obj);
    for (i = 1; i < len; i+=2) {
        PyObject *py_property = PyTuple_GetItem(args, i);
        PyObject *py_value = PyTuple_GetItem(args, i + 1);
        gchar *property_name;
        GParamSpec *pspec;
        GValue value = { 0 };

        if (!PyString_Check(py_property)) {
            PyErr_SetString(PyExc_TypeError,
                            "Expected string argument for property.");
            return NULL;
        }

        property_name = PyString_AsString(py_property);

        pspec = gtk_container_class_find_child_property(class, property_name);
        if (!pspec) {
            gchar buf[512];
            g_snprintf(buf, sizeof(buf),
                       "container does not support property `%s'",
                       property_name);
            PyErr_SetString(PyExc_TypeError, buf);

            return NULL;
        }

        g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));

        pyg_value_from_pyobject(&value, (PyObject*)py_value);

        gtk_container_child_set_property(container, child, property_name, &value);

        g_value_unset(&value);
    }
    Py_INCREF(Py_None);
    return Py_None;
}
%%
override gtk_container_child_get
static PyObject *
_wrap_gtk_container_child_get(PyGObject *self, PyObject *args)
{
    PyGObject *pychild;
    GtkContainer *container;
    GtkWidget *child;
    GList *children;
    GObjectClass *class;
    int len, i;
    PyObject *tuple;

    if ((len = PyTuple_Size(args)) < 1) {
        PyErr_SetString(PyExc_TypeError, "requires at least one argument");
        return NULL;
    }
    pychild = (PyGObject*)PyTuple_GetItem(args, 0);
    if (!pygobject_check(pychild, &PyGtkWidget_Type)) {
        PyErr_SetString(PyExc_TypeError,
                        "first argument should be a GtkWidget");
        return NULL;
    }

    container = GTK_CONTAINER(self->obj);
    child = GTK_WIDGET(pychild->obj);

    children = gtk_container_get_children(container);
    if (g_list_find(children, child) == NULL) {
        PyErr_SetString(PyExc_TypeError,
                        "first argument must be a child");
        return NULL;
    }

    tuple = PyTuple_New(len-1);
    class = G_OBJECT_GET_CLASS(self->obj);
    for (i = 1; i < len; i++) {
        PyObject *py_property = PyTuple_GetItem(args, i);
        gchar *property_name;
        GParamSpec *pspec;
        GValue value = { 0 };
        PyObject *item;

        if (!PyString_Check(py_property)) {
            PyErr_SetString(PyExc_TypeError,
                            "Expected string argument for property.");
            return NULL;
        }

        property_name = PyString_AsString(py_property);

        pspec = gtk_container_class_find_child_property(class, property_name);
        if (!pspec) {
            gchar buf[512];
            g_snprintf(buf, sizeof(buf),
                       "container does not support property `%s'",
                       property_name);
            PyErr_SetString(PyExc_TypeError, buf);

            return NULL;
        }

        g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));

        gtk_container_child_get_property(container, child, property_name, &value);

        item = pyg_value_as_pyobject(&value, TRUE);
        PyTuple_SetItem(tuple, i-1, item);

        g_value_unset(&value);
    }
    return tuple;
}
%%
override gtk_container_add_with_properties
static PyObject *
_wrap_gtk_container_add_with_properties(PyGObject *self, PyObject *args)
{
    PyGObject *pychild;
    GtkContainer *container;
    GtkWidget *child;
    GObjectClass *class;
    int len, i;

    if ((len = PyTuple_Size(args)) < 1) {
        PyErr_SetString(PyExc_TypeError, "requires at least one argument");
        return NULL;
    }
    pychild = (PyGObject*)PyTuple_GetItem(args, 0);
    if (!pygobject_check(pychild, &PyGtkWidget_Type)) {
        PyErr_SetString(PyExc_TypeError,
                        "first argument should be a GtkWidget");
        return NULL;
    }

    container = GTK_CONTAINER(self->obj);
    child = GTK_WIDGET(pychild->obj);

    if ((len - 1) % 2) {
        PyErr_SetString(PyExc_TypeError,
                        "Argument list must be column, value pairs.  No -1 "
                        "termination is needed.");
        return NULL;
    }

    gtk_widget_freeze_child_notify(child);

    gtk_container_add(container, child);

    class = G_OBJECT_GET_CLASS(self->obj);
    for (i = 1; i < len; i+=2) {
        PyObject *py_property = PyTuple_GetItem(args, i);
        PyObject *py_value = PyTuple_GetItem(args, i + 1);
        gchar *property_name;
        GParamSpec *pspec;
        GValue value = { 0 };

        if (!PyString_Check(py_property)) {
            PyErr_SetString(PyExc_TypeError,
                            "Expected string argument for property.");
            return NULL;
        }

        property_name = PyString_AsString(py_property);

        pspec = gtk_container_class_find_child_property(class, property_name);
        if (!pspec) {
            gchar buf[512];
            g_snprintf(buf, sizeof(buf),
                       "container does not support property `%s'",
                       property_name);
            PyErr_SetString(PyExc_TypeError, buf);

            return NULL;
        }

        g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));

        pyg_value_from_pyobject(&value, (PyObject*)py_value);

        gtk_container_child_set_property(container, child, property_name, &value);

        g_value_unset(&value);
    }

    gtk_widget_thaw_child_notify(child);

    Py_INCREF(Py_None);
    return Py_None;
}
%%
override gtk_container_foreach
static void
pygtk_container_for_common_marshal(GtkWidget *widget,
				   gpointer data)
{
    PyGILState_STATE state;
    PyGtkCustomNotify *cunote = data;
    PyObject *py_widget, *retobj;

    g_assert(cunote->func);

    state = pyg_gil_state_ensure();

    py_widget = pygobject_new((GObject*)widget);
    if (cunote->data)
        retobj = PyEval_CallFunction(cunote->func, "(NO)",
                                     py_widget, cunote->data);
    else
        retobj = PyEval_CallFunction(cunote->func, "(N)",
                                     py_widget);

    if (retobj == NULL) {
        PyErr_Print();
    }

    Py_XDECREF(retobj);

    pyg_gil_state_release(state);
}
static PyObject *
pygtk_container_for_common(PyGObject *self, PyObject *args, unsigned for_index)
{
    PyObject *pyfunc, *pyarg = NULL;
    PyGtkCustomNotify cunote;
    static struct {
        char *parse_arg;
        void (*for_func)(GtkContainer *container, GtkCallback callback,
                          gpointer callback_data);
    } table[] = {
            { "O|O:GtkContainer.foreach", gtk_container_foreach },
            { "O|O:GtkContainer.forall", gtk_container_forall }
    };

    if (for_index >= countof(table)) {
	PyErr_SetString(PyExc_TypeError, "for_index > 2");
	return NULL;
    }

    if (!PyArg_ParseTuple(args, table[for_index].parse_arg,
                          &pyfunc, &pyarg))
         return NULL;
 
    cunote.func = pyfunc;
    cunote.data = pyarg;
    table[for_index].for_func(GTK_CONTAINER(self->obj),
			      pygtk_container_for_common_marshal,
			      &cunote);
    Py_INCREF(Py_None);
    return Py_None;
}
static PyObject *
_wrap_gtk_container_foreach(PyGObject *self, PyObject *args)
{
    return pygtk_container_for_common(self, args, PYGTK_CONTAINER_FOREACH);
}
%%
override gtk_container_forall
static PyObject *
_wrap_gtk_container_forall(PyGObject *self, PyObject *args)
{
    return pygtk_container_for_common(self, args, PYGTK_CONTAINER_FORALL);
}
%%
override gtk_container_class_list_child_properties kwargs
static PyObject *
_wrap_gtk_container_class_list_child_properties (PyObject *self, PyObject *args,
					      PyObject*kwargs)
{
    static char *kwlist[] = { "klass", NULL };
    GParamSpec **specs;
    PyObject *py_itype, *list;
    GType itype;
    GObjectClass *class;
    guint nprops;
    guint i;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
				     "O:gtk.container_class_list_child_properties", kwlist,
				     &py_itype))
	return NULL;
    
    if ((itype = pyg_type_from_object(py_itype)) == 0)
	return NULL;

    if (!g_type_is_a(itype, G_TYPE_OBJECT)) {
	PyErr_SetString(PyExc_TypeError, "type must be derived from GObject");
	return NULL;
    }

    class = g_type_class_ref(itype);
    if (!class) {
	PyErr_SetString(PyExc_RuntimeError,
			"could not get a reference to type class");
	return NULL;
    }

    specs = gtk_container_class_list_child_properties(class, &nprops);
    list = PyTuple_New(nprops);
    if (list == NULL) {
	g_free(specs);
	g_type_class_unref(class);
	return NULL;
    }
    
    for (i = 0; i < nprops; i++) {
	PyTuple_SetItem(list, i, pyg_param_spec_new(specs[i]));
    }
    
    g_free(specs);
    g_type_class_unref(class);

    return list;
}
%%
define GtkContainer.list_child_properties noargs classmethod
static PyObject *
_wrap_gtk_container_list_child_properties (PyObject *self, PyObject *args,
                                           PyObject*kwargs)
{
    GParamSpec **specs;
    PyObject *list;
    GType itype;
    GObjectClass *class;
    guint nprops;
    guint i;

    if ((itype = pyg_type_from_object(self)) == 0)
	return NULL;

    class = g_type_class_ref(itype);
    if (!class) {
	PyErr_SetString(PyExc_RuntimeError,
			"could not get a reference to type class");
	return NULL;
    }

    specs = gtk_container_class_list_child_properties(class, &nprops);
    list = PyList_New(nprops);
    if (list == NULL) {
	g_free(specs);
	g_type_class_unref(class);
	return NULL;
    }
    
    for (i = 0; i < nprops; i++) {
	PyList_SetItem(list, i, pyg_param_spec_new(specs[i]));
    }
    
    g_free(specs);
    g_type_class_unref(class);

    return list;
}

%%
override gtk_container_class_install_child_property kwargs
static PyObject *
_wrap_gtk_container_class_install_child_property (PyObject *self,
					       PyObject *args,
					       PyObject* kwargs)
{
    static char *kwlist[] = { "klass", "property_id", "pspec", NULL };
    PyObject *py_itype, *property;
    GType itype;
    GtkContainerClass *class;
    guint property_id;
    GParamSpec *pspec;

    if (PyErr_Warn(PyExc_DeprecationWarning, "use the gtk.Container.install_child_property classmethod"))
        return NULL;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
				     "OiO:container_class_install_child_property",
				     kwlist,
				     &py_itype, &property_id, &property))
	return NULL;


    if ((itype = pyg_type_from_object(py_itype)) == 0)
	return NULL;

    if (!g_type_is_a(itype, GTK_TYPE_CONTAINER)) {
	PyErr_SetString(PyExc_TypeError, "type must be derived from GtkContainer");
	return NULL;
    }

    class = g_type_class_ref(itype);
    if (!class) {
	PyErr_SetString(PyExc_RuntimeError,
			"could not get a reference to type class");
	return NULL;
    }

    pspec = pyg_param_spec_from_object(property);
    if(!pspec) {
	g_type_class_unref(class);
	return NULL;
    }

    if (gtk_container_class_find_child_property(G_OBJECT_CLASS(class), pspec->name)) {
	PyErr_Format(PyExc_TypeError,
		     "there is already a '%s' property installed", pspec->name);
	g_type_class_unref(class);
	return NULL;
    }
    
    gtk_container_class_install_child_property(class, property_id, pspec);
	
    g_type_class_unref(class);

    Py_INCREF(Py_None);
    return Py_None;
}

%%
define GtkContainer.install_child_property kwargs classmethod
static PyObject *
_wrap_gtk_container_install_child_property (PyObject *self,
                                            PyObject *args,
                                            PyObject* kwargs)
{
    static char *kwlist[] = { "property_id", "pspec", NULL };
    PyObject *property;
    GType itype;
    GtkContainerClass *class;
    guint property_id;
    GParamSpec *pspec;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
				     "iO:container_class_install_child_property",
				     kwlist,
				     &property_id, &property))
	return NULL;


    if ((itype = pyg_type_from_object(self)) == 0)
	return NULL;

    class = g_type_class_ref(itype);
    if (!class) {
	PyErr_SetString(PyExc_RuntimeError,
			"could not get a reference to type class");
	return NULL;
    }

    pspec = pyg_param_spec_from_object(property);
    if(!pspec) {
	g_type_class_unref(class);
	return NULL;
    }

    if (gtk_container_class_find_child_property(G_OBJECT_CLASS(class), pspec->name)) {
	PyErr_Format(PyExc_TypeError,
		     "there is already a '%s' property installed", pspec->name);
	g_type_class_unref(class);
	return NULL;
    }
    
    gtk_container_class_install_child_property(class, property_id, pspec);
	
    g_type_class_unref(class);

    Py_INCREF(Py_None);
    return Py_None;
}

%%
override-slot GtkContainer.tp_iter

typedef struct {
    PyObject_HEAD
    GList *list;
} PyGContainerIter;

static void
pyg_container_iter_dealloc(PyGContainerIter *self)
{
    g_list_free(self->list);
    PyObject_Del((PyObject*) self);
}

static PyObject*
pygobject_container_iter_next(PyGContainerIter *iter)
{
    PyObject *child;
    
    if (!iter->list) {
        PyErr_SetNone(PyExc_StopIteration);
        return NULL;
    }
	
    child = pygobject_new((GObject*)iter->list->data);
    iter->list = g_list_next(iter->list);
    return child;
}

static PyTypeObject PyGContainerIter_Type = {
	PyObject_HEAD_INIT(NULL)
	0,					/* ob_size */
	"gobject.GContainerIter",		/* tp_name */
	sizeof(PyGContainerIter),		/* tp_basicsize */
	0,					/* tp_itemsize */
	(destructor)pyg_container_iter_dealloc,	/* tp_dealloc */
	0,					/* tp_print */
	0,					/* tp_getattr */
	0,					/* tp_setattr */
	0,					/* tp_compare */
	0,					/* tp_repr */
	0,					/* tp_as_number */
	0,					/* tp_as_sequence */
	0,		       			/* tp_as_mapping */
	0,					/* tp_hash */
	0,					/* tp_call */
	0,					/* tp_str */
	0,					/* tp_getattro */
	0,					/* tp_setattro */
	0,					/* tp_as_buffer */
	Py_TPFLAGS_DEFAULT,			/* tp_flags */
 	"GtkContainer child iterator",		/* tp_doc */
	0,					/* tp_traverse */
 	0,					/* tp_clear */
	0,					/* tp_richcompare */
	0,					/* tp_weaklistoffset */
	0,					/* tp_iter */
	(iternextfunc)pygobject_container_iter_next, /* tp_iternext */
};

static PyObject*
_wrap_gtk_container_tp_iter(PyGObject *self)
{
    PyGContainerIter *iter;
    iter = PyObject_NEW(PyGContainerIter, &PyGContainerIter_Type);
    iter->list = gtk_container_get_children(GTK_CONTAINER(self->obj));
    return (PyObject *) iter;
}
%%
override-slot GtkContainer.tp_as_sequence
static Py_ssize_t
_wrap_gtk_container_sq_length(PyGObject *self)
{
    return g_list_length(gtk_container_get_children(GTK_CONTAINER(self->obj)));
}

static PySequenceMethods _wrap_gtk_container_tp_as_sequence = {
    (lenfunc)_wrap_gtk_container_sq_length,
    0,
    0,
    0,
    0,
    0,
    0,
};
%%
override-slot GtkContainer.tp_as_number
static int
_wrap_gtk_container_nb_nonzero(PyGObject *self)
{
    return 1;
}

static PyNumberMethods _wrap_gtk_container_tp_as_number = {
    (binaryfunc)0,
    (binaryfunc)0,
    (binaryfunc)0,
    (binaryfunc)0,
    (binaryfunc)0,
    (binaryfunc)0,
    (ternaryfunc)0,
    (unaryfunc)0,
    (unaryfunc)0,
    (unaryfunc)0,
    (inquiry)_wrap_gtk_container_nb_nonzero
};

%%
override GtkContainer__proxy_do_forall

typedef struct {
    GtkCallback    func;
    gpointer       func_data;
} PyGtkContainerDataFuncData;


static PyObject *
_wrap_GtkContainerDataFunc(PyObject *self, PyObject *args)
{
    PyObject *py_widget;
    PyObject *py_data;
    PyGtkContainerDataFuncData *data;

    if (!PyArg_ParseTuple(args, "O!O!",
			  &PyGtkWidget_Type, &py_widget,
                          &PyCObject_Type, &py_data))
        return NULL;
    
    data = PyCObject_AsVoidPtr(py_data);
    data->func(GTK_WIDGET(pygobject_get(py_widget)), data->func_data);
    
    Py_INCREF(Py_None);
    return Py_None;
}

static void
_wrap_GtkContainer__proxy_do_forall (GtkContainer *container,
				     gboolean      include_internals,
				     GtkCallback   callback,
				     gpointer      callback_data)
{
    PyGILState_STATE state;
    PyObject *self, *py_func, *py_func_data;
    PyMethodDef pyfunc_def = { "GtkContainer.do_forall callback",
			       (PyCFunction)_wrap_GtkContainerDataFunc,
                               METH_VARARGS|METH_KEYWORDS };
    PyGtkContainerDataFuncData *data;

    state = pyg_gil_state_ensure();
    
    self = pygobject_new((GObject *)container);
    py_func = PyCFunction_NewEx(&pyfunc_def, NULL, NULL);
    
    data = g_new(PyGtkContainerDataFuncData, 1);
    data->func = callback;
    data->func_data = callback_data;
    PyObject_Repr(self);
    PyObject_Repr(py_func);
    py_func_data = PyCObject_FromVoidPtr(data, g_free);
    if (!PyObject_CallMethod(self, "do_forall", "ONN", 
			     include_internals ? Py_True : Py_False, py_func,
			     py_func_data))
	PyErr_Print();
    
    pyg_gil_state_release(state);
}
%%
override GtkContainer__proxy_do_set_child_property
static void
_wrap_GtkContainer__proxy_do_set_child_property (GtkContainer *container,
                                                 GtkWidget *child,
                                                 guint property_id,
                                                 const GValue *value,
                                                 GParamSpec *pspec)
{
    PyGILState_STATE state;
    PyObject *self, *py_ret;

    state = pyg_gil_state_ensure();
    self = pygobject_new((GObject *) container);

    py_ret = PyObject_CallMethod(self, "do_set_child_property", "NNNN",
                                 pygobject_new((GObject *) child),
                                 PyLong_FromUnsignedLong(property_id),
                                 pyg_value_as_pyobject(value, FALSE),
                                 pyg_param_spec_new(pspec));
    if (!py_ret) {
	PyErr_Print();
	Py_DECREF(self);
	pyg_gil_state_release(state);
	return;
    }
    Py_DECREF(self);
    if (py_ret != Py_None)
        PyErr_Warn(PyExc_Warning, "do_set_child_property must return None");
    Py_DECREF(py_ret);

    pyg_gil_state_release(state);
}

%%
override GtkContainer__proxy_do_get_child_property
static void
_wrap_GtkContainer__proxy_do_get_child_property (GtkContainer *container,
                                                 GtkWidget *child,
                                                 guint property_id,
                                                 GValue *value,
                                                 GParamSpec *pspec)
{
    PyGILState_STATE state;
    PyObject *self, *py_ret;

    state = pyg_gil_state_ensure();

    self = pygobject_new((GObject*)container);
    py_ret = PyObject_CallMethod(self, "do_get_child_property", "NNN",
                                 pygobject_new((GObject *) child),
                                 PyLong_FromUnsignedLong(property_id),
                                 pyg_param_spec_new(pspec));
    if (!py_ret) {
	PyErr_Print();
	Py_DECREF(self);
	pyg_gil_state_release(state);
	return;
    }
    Py_DECREF(self);
    pyg_value_from_pyobject(value, py_ret);
    Py_DECREF(py_ret);

    pyg_gil_state_release(state);
}

%%
override GtkContainer__do_set_child_property kwargs
static PyObject *
_wrap_GtkContainer__do_set_child_property(PyObject *cls, PyObject *args, PyObject *kwargs)
{
    gpointer klass;
    static char *kwlist[] = { "self", "child", "property_id", "value", "pspec", NULL };
    PyGObject *self, *child;
    PyObject *py_property_id = NULL, *py_value, *py_pspec;
    guint property_id = 0;
    GValue value = {0, };

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!O!OOO!:GtkContainer.set_child_property",
                                     kwlist, &PyGtkContainer_Type, &self,
                                     &PyGtkWidget_Type, &child,
                                     &py_property_id,
                                     &py_value,
                                     &PyGParamSpec_Type, &py_pspec))
        return NULL;

    if (pyg_value_from_pyobject(&value, py_value)) {
        PyErr_SetString(PyExc_TypeError, "unable to convert value");
        return NULL;
    }

    if (py_property_id) {
        if (PyLong_Check(py_property_id))
            property_id = PyLong_AsUnsignedLong(py_property_id);
        else if (PyInt_Check(py_property_id))
            property_id = PyInt_AsLong(py_property_id);
        else
            PyErr_SetString(PyExc_TypeError, "Parameter 'property_id' must be an int or a long");
        if (PyErr_Occurred())
            return NULL;
    }
    klass = g_type_class_ref(pyg_type_from_object(cls));
    if (GTK_CONTAINER_CLASS(klass)->set_child_property)
        GTK_CONTAINER_CLASS(klass)->set_child_property(GTK_CONTAINER(self->obj), GTK_WIDGET(child->obj), property_id,
                                                       &value, ((PyGParamSpec *)py_pspec)->pspec);
    else {
        PyErr_SetString(PyExc_NotImplementedError, "virtual method GtkContainer.set_child_property not implemented");
        g_type_class_unref(klass);
        return NULL;
    }
    g_type_class_unref(klass);
    Py_INCREF(Py_None);
    return Py_None;
}

%%
override GtkContainer__do_get_child_property kwargs
static PyObject *
_wrap_GtkContainer__do_get_child_property(PyObject *cls, PyObject *args, PyObject *kwargs)
{
    gpointer klass;
    static char *kwlist[] = { "self", "child", "property_id", "pspec", NULL };
    PyGObject *self, *child;
    PyObject *py_property_id = NULL;
    guint property_id = 0;
    GValue value = {0, };
    PyObject *py_value, *py_pspec;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!O!OO!:GtkContainer.get_child_property", kwlist,
                                     &PyGtkContainer_Type, &self,
                                     &PyGtkWidget_Type, &child,
                                     &py_property_id,
                                     &PyGParamSpec_Type, &py_pspec))
        return NULL;
    if (py_property_id) {
        if (PyLong_Check(py_property_id))
            property_id = PyLong_AsUnsignedLong(py_property_id);
        else if (PyInt_Check(py_property_id))
            property_id = PyInt_AsLong(py_property_id);
        else
            PyErr_SetString(PyExc_TypeError, "Parameter 'property_id' must be an int or a long");
        if (PyErr_Occurred())
            return NULL;
    }
    klass = g_type_class_ref(pyg_type_from_object(cls));
    if (GTK_CONTAINER_CLASS(klass)->get_child_property)
        GTK_CONTAINER_CLASS(klass)->get_child_property(GTK_CONTAINER(self->obj), GTK_WIDGET(child->obj), property_id,
                                                       &value, ((PyGParamSpec *)py_pspec)->pspec);
    else {
        PyErr_SetString(PyExc_NotImplementedError, "virtual method GtkContainer.get_child_property not implemented");
        g_type_class_unref(klass);
        return NULL;
    }
    g_type_class_unref(klass);
    
    py_value = pyg_value_as_pyobject(&value, TRUE);
    g_value_unset(&value);
    return py_value;
}

%%
override GtkContainer__do_forall kwargs

typedef struct {
    PyObject *callback;
    PyObject *callback_data;
} PyGtkContainerPyCallbackData;

static void
_wrap_GtkContainer__do_forall_callback(GtkWidget *child, PyGtkContainerPyCallbackData *data)
{
    PyObject *pychild = pygobject_new((GObject *) child);
    PyObject *result;

    result = PyObject_CallFunctionObjArgs(data->callback, pychild, data->callback_data, NULL);
    /* Just discard it. */
    Py_DECREF(result);
}

static PyObject *
_wrap_GtkContainer__do_forall(PyObject *cls, PyObject *args, PyObject *kwargs)
{
    gpointer klass;
    static char *kwlist[] = { "self", "include_internals", "callback", "callback_data", NULL };
    PyGObject *self;
    char include_internals;
    PyObject *callback;
    PyObject *callback_data = NULL;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!bO|O:GtkContainer.forall", kwlist,
                                     &PyGtkContainer_Type, &self,
                                     &include_internals,
                                     &callback, &callback_data))
        return NULL;

    klass = g_type_class_ref(pyg_type_from_object(cls));
    if (GTK_CONTAINER_CLASS(klass)->forall) {
	PyGtkContainerPyCallbackData *data = g_new(PyGtkContainerPyCallbackData, 1);
	data->callback = callback;
	data->callback_data = callback_data;

	GTK_CONTAINER_CLASS(klass)->forall(GTK_CONTAINER(self->obj),
					   include_internals,
					   (GtkCallback)_wrap_GtkContainer__do_forall_callback,
					   data);
	g_free(data);
        g_type_class_unref(klass);
	Py_INCREF(Py_None);
	return Py_None;
    }
    else {
        PyErr_SetString(PyExc_NotImplementedError, "virtual method GtkContainer.forall not implemented");
        g_type_class_unref(klass);
        return NULL;
    }
}
